package com.acme.team02.chat.server;

import java.sql.SQLException;
import java.util.List;

import com.acme.team02.chat.server.domain.Message;
import com.acme.team02.chat.server.domain.User;

public class MessageManager {

	private UserManager userManager;
	private DatabaseConnectivity historyDB;
	
	
	private final User SERVER_USER = new User(null, "Server");

	public MessageManager(UserManager userManager, DatabaseConnectivity databaseConnectivity) {
		this.userManager = userManager;
		this.historyDB = databaseConnectivity;
		this.historyDB.connect();
	}

	/**
	 * Message processor
	 * @param user message author
	 * @param strMessage message
	 */
	public void onGetMessage(User user, String strMessage) {
		if (strMessage.startsWith("/")) {
			processCommand(user, strMessage);
		} else {
			sendMessage(user, new Message(SERVER_USER, "no command given"));
		}

	}

	private void processMessageSend(User user, String strMessage) {
		Message message = new Message(user, strMessage);
		try {
			historyDB.addMessage(message);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		broadcastMessage(message);
	}

	/**
	 * send message to user
	 * @param user user
	 * @param message message
	 */
	public void sendMessage(User user, Message message) {
		user.sendMessage(message);
	}

	private void processCommand(User user, String message) {
		int spacePos = message.indexOf(" ");
		String cmd;
		String argument;
		if (spacePos != -1) {
			cmd = message.substring(0, spacePos);
			argument = message.substring(spacePos + 1);
		} else {
			cmd = message;
			argument = "";
		}
		switch (cmd) {
		case "/snd":
			processMessageSend(user, argument);
			break;
		case "/hist":
			processHistoryCommand(user);
			break;
		case "/chid":
			processChangeNameCommand(user, argument);
			break;
		case "/chroom":{
			processChangeRoomCommand(user, argument);
			break;
		}
		case "/sdnp":{
			processPrivateMsgCommand(user,argument);
			break;
		}
		default:
			sendMessage(user, new Message(SERVER_USER, "unknown command"));
			break;

		}
	}


	private void processPrivateMsgCommand(User user, String argument) {
		int spacePos = argument.indexOf(" ");
		String receiver;
		String msg;

		if (spacePos != -1) {
			receiver = argument.substring(0, spacePos);
			msg = argument.substring(spacePos + 1);
		} else {
			receiver = argument;
			msg = "";
		}
		
		for (User userIter : userManager.getUserList()) {
			if (userIter.getRoom().equals(user.getRoom()) && userIter.getUserName().equals(receiver)) {
				Message privateMsgToReceiver = new Message(user,"PRIVATE FROM " + user.getUserName() + ": " + msg);
				userIter.sendMessage(privateMsgToReceiver);
				Message privateMsgToSender = new Message(user,"PRIVATE FOR " + receiver + ": " + msg);
				user.sendMessage(privateMsgToSender);
				return;
			}
		}
		Message privateMsgToSender = new Message(SERVER_USER,"user " + receiver + " not found");
		user.sendMessage(privateMsgToSender);
	}

	private void processHistoryCommand(User user) {
		StringBuilder histText = new StringBuilder();
		
		List<Message> list = historyDB.getHistory(user.getRoom());
		
		for (Message msg : list) {
			if (msg.getRoom().equals(user.getRoom())) {
				histText.append("\\n   ").append(msg.toString());
			}
		}
		sendMessage(user, new Message(SERVER_USER, histText.toString()));
	}

	private void processChangeNameCommand(User user, String nName) {
		user.setUserName(nName);
		sendMessage(user, new Message(SERVER_USER, "Your new name is " + nName));
	}
	
	private void processChangeRoomCommand(User user, String nRoom){
		user.setRoom(nRoom);
		sendMessage(user, new Message(SERVER_USER, "Your are in " + nRoom));
	}

	private void broadcastMessage(Message message) {
		for (User user : userManager.getUserList()) {
			if (user.getRoom().equals(message.getRoom())) {
				user.sendMessage(message);
			}
		}
	}

}
